<template>
	<view class="y-flex y-flex-1 position-relative" style="background-color: rgba(0,0,0,.2);">
		<web-view class="y-flex-1" ref="webview" src="/hybrid/html/video/my-live-player.html" @onPostMessage="handleMessage"></web-view>
		<com-popup position="absolute" :visible.sync="modalShow" direction="bottom" @hide="handleModalHide">
			<view class="y-flex" :style="{'background-color': pageStyle.background, 'height': modalHeight + 'px'}">
				<module-list
				ref="list"
				:params="modalParams"
				:component="components"
				:cell="cell"
				:comment="comments"
				:bounce="pageStyle.enableBounce"
				:back-top-show="pageStyle.enableBackTop"
				:refreshImage="pageStyle.pulldownRefreshImage"
				:pulldownable="pageStyle.enablePulldown == 1"
				:loadmoreable="pageStyle.enableLoadmore == 1"
				:loadingColor="pageStyle.loadingColor"
				:backTopImage="pageStyle.backTopImage"
				@pulldown="handleModalPulldown">
					<template #top v-if="detail && detail.title">
						<cell v-if="detail && detail.title">
							<find-detail ref="detail"
							:data="detail"
							:options="detailOptions"
							:bg-color="componentStyle['background-color']"
							:style="componentStyle"
							@utils="handleUtils"></find-detail>
						</cell>
						<cell v-if="items && items.length > 0">
							<find-items :data="items" :options="itemOptions" :style="componentStyle" @moreClick="handleMoreClick" @itemClick="handleItemClick"></find-items>
						</cell>
					</template>
				</module-list>
			</view>
		</com-popup>
	</view>
</template>

<script>
	import { openDB, closeDB, select, insert, update, remove } from '@/assets/database'
	import { pixelunit, hexToRgba } from '@/assets/js/util.js'
	import { setVolume, getVolume, saveBase64ImageToAlbum } from '@/assets/js/native.js'
	import ModuleList from './components/ModuleList.vue'
	import FindDetail from './components/FindModule/FindDetail.vue'
	import FindItems from './components/FindModule/FindItems.vue'
	export default {
		inject: ['getPage', 'getPageStyle', 'getComponentStyle', 'getSkinColor', 'getQuery', 'getInnerHeight', 'getNavbarHeight', 'navigate', 'confirm', 'toast', 'showVolume', 'showItems'],
		components: {ModuleList, FindDetail, FindItems},
		computed: {
			history () {
				return this.$store.getters['setting/GET_HISTORY']
			},
			autoplay () {
				return this.$store.getters['setting/GET_VIDEO_AUTOPLAY']
			},
			skinColor () {
				return this.getSkinColor()
			},
			network () {
				return this.$store.getters['network/GET']
			},
			//获取路由参数
			query () {
				return this.getQuery()
			},
			modalHeight () {
				return this.getInnerHeight() - (this.pageStyle?.enableNavigationTransparent ? this.getNavbarHeight() : 0)
			},
			page () {
				return this.getPage()
			},
			pageStyle () {
				return this.getPageStyle()
			},
			componentStyle () {
				const style = this.getComponentStyle()
				return {
					'margin-top': pixelunit(style.marginTop),
					'margin-bottom': pixelunit(style.marginBottom),
					'margin-left': pixelunit(style.marginLeft),
					'margin-right': pixelunit(style.marginRight),
					'background-color': hexToRgba(style.backgroundColor, style.backgroundOpacity),
					'border-radius': pixelunit(style.borderRadius)
				}
			},
			detailOptions () {
				return {
					enableButton: 0
				}
			},
			itemOptions () {
				return {
					title: '直播列表',
					unit: "个"
				}
			},
			cell () {
				return this.page?.cell || {}
			},
			comments () {
				return this.page?.comments || {}
			},
			components () {
				return this.page?.components || []
			},
			modalParams () {
				return Object.assign({}, this.query, this.detail)
			}
		},
		data () {
			return {
				detail: {},//详情信息
				items: [],//分集
				modalShow: false,//更多模块展示
				current: -1//当前播放索引
			}
		},
		methods: {
			onBackPress () {
				if ( this.modalShow ) {
					this.modalShow = false
					return true
				}
				if ( this.detail.uniqueId && this.current >= 0 ) {
					if ( this.history == 0 ) {
						this.confirm({
							title: '记录提示',
							content: '当前看到第' + (this.current + 1) + '个直播' + '\n\n是否记录',
							cancelText: '取消记录',
							confirmText: '保存记录',
							success: res => {
								if ( res.confirm ) {
									this.saveRecord()
								} else {
									uni.navigateBack()
								}
							}
						})
					} else if ( this.history == 1 ) this.saveRecord()
					else uni.navigateBack()
					return true
				}
				return false
			},
			onShow () {
				this.$refs.detail && this.$refs.detail.getRecord()
			},
			handleMessage (e) {
				e.detail.data.forEach(item => {
					if ( item.ready ) {
						this.handlePulldown()
					}
					if ( item.voice ) {
						this.showVolume()
					}
					if ( item.more ) {
						this.showModal()
					}
					if ( item.workchange ) {
						this.playvideo(item.workchange.index)
					}
					if ( item.seeklight >= 0 ) {
						uni.setScreenBrightness({
							value: item.seeklight
						})
					}
					if ( item.seekvolume >= 0 ) {
						setVolume(item.seekvolume)
					}
					if ( item.capturesaved ) {
						if ( item.capturesaved.code != 200 ) {
							saveBase64ImageToAlbum(item.capturesaved.data.base64, item.capturesaved.fileName).then(path => {
								this.showToast('保存到相册成功')
							}).catch(() => {
								this.showToast('保存到相册失败')
							})
						}
					}
					if ( item.directionchange ) {
						if ( item.directionchange.code != 200 ) {//锁定屏幕方向失败
							var direction = item.directionchange.to//预期屏幕方向
							if ( direction ) plus.screen.lockOrientation(direction)//锁定屏幕方向
							else plus.screen.unlockOrientation()//解除屏幕方向锁定
						}
					}
				})
			},
			handleUtils (e) {
				this.$emit('utils', e)
			},
			handleMoreClick () {
				this.showItems({
					title: '选集',
					data: this.items,
					current: this.current,
					defaultTitle: this.detail.title,
					unit: '集',
					success: res => {
						if ( res.confirm ) {
							this.modalShow = false
							this.playvideo(res.current)
						}
					}
				})
			},
			handleItemClick (e) {
				this.modalShow = false
				this.playvideo(e.index)
			},
			async saveRecord () {
				try{
					await openDB()
					if ( this.record.id ) {
						await update('record', {
							url: this.detail.url,
							title: this.detail.title || '',
							cover: this.detail.cover || '',
							current: this.current,
							current_title: this.items[this.current]?.title || '第' + (this.current + 1) + '个直播',
							is_adult: this.detail.isAdult,
							source_id: this.detail.sourceId
						}, 'id = ' + this.record.id)
					} else {
						await insert('record', {
							unique_id: this.detail.uniqueId,
							url: this.detail.url,
							title: this.detail.title || '',
							cover: this.detail.cover || '',
							current: this.current,
							current_title: this.items[this.current]?.title || '第' + (this.current + 1) + '个直播',
							is_adult: this.detail.isAdult,
							source_id: this.detail.sourceId
						})
					}
					closeDB()
					uni.navigateBack()
				}catch(e){
					closeDB()
					uni.showToast({
						title: e.message,
						icon: 'none'
					})
					setTimeout(() => {
						uni.navigateBack()
					}, 500)
				}
			},
			async playvideo (current) {
				if ( !this.items || !this.items.length ) {
					this.toast('未找到直播列表')
					return
				}
				this.current = current
				let item = this.items[current]
				uni.showLoading({
					title: '加载中'
				})
				try{
					if ( !item.src ) item = Object.assign({}, item, await this.handleGetContext(item))
					if ( !item.barrages ) {
						const barrages = await this.handleGetBarrages(item)
						item.barrages = barrages
					}
				}catch(e){}
				uni.hideLoading()
				this.$set(this.items, current, item)
				if ( !item.src ) {
					this.toast('未找到播放链接')
					return
				}
				uni.getScreenBrightness({
					success: res => {
						const arg = {
							src: item.src,
							title: item.title || item.name || this.detail.title,
							subtitle: item.subtitle || this.detail.subtitle,
							desciption: item.desciption || this.detail.desciption,
							poster: item.cover || item.poster || this.detail.cover,
							autoplay: this.autoplay,
							type: item.type || this.detail.type,
							barrages: item.barrages,
							isLive: item.isLive,
							initialVolume: getVolume(),
							initialLight: res.value,
							workIndex: current,
							works: this.items
						}
						this.$refs.webview && this.$refs.webview.evalJS(`setVideo('${encodeURIComponent(JSON.stringify(arg))}');`)
					}
				})
			},
			async handlePulldown (callback) {
				try{
					this.detail = await this.handleGetDetail()
					this.items = await this.handleGetItems()
					this.$nextTick(function () {
						this.$refs.detail && this.$refs.detail.getRecord()
						this.$nextTick(() => {
							this.playvideo(this.$refs.detail.record.current || 0)
							this.$emit('loaded', true)
						})
					})
				}catch(e){
					this.$emit('loaded', true)
				}
			},
			async handleGetDetail () {
				const detail = this.page?.detail || {}
				const staticData = await this.network.staticDataHandle(detail.staticData || {}, this.query)
				const dynamicData = detail.dynamicData
				const request = detail.request
				let data = {}
				if ( dynamicData && request ) {
					const newRequest = await this.network.requestHandle(request, this.query)
					const response = await this.network.$request(newRequest)
					data = await this.network.$list(dynamicData, response.data, response.taskId)
					data.uniqueId = data.id || this.network.getUniqueId(newRequest)
					if ( !data.shareUrl && !staticData.shareUrl ) data.shareUrl = await this.network.getShareUrl(newRequest)
				}
				return Object.assign({}, staticData, data)
			},
			async handleGetItems () {
				const items = this.page?.items || {}
				const params = Object.assign({}, this.query, this.detail)
				const staticData = items.staticData ? await this.network.staticDataHandle(items.staticData, params) : []
				const dynamicData = items.dynamicData
				const request = items.request
				let data = []
				if ( dynamicData && request ) {
					const newRequest = await this.network.requestHandle(request, params)
					const response = await this.network.$request(newRequest)
					data = await this.network.$list(dynamicData, response.data, response.taskId)
				}
				return staticData.concat(data).map(s => Object.assign({}, s, { loading: false, isLive: s.isLive == 1 ? true : s.isLive == 0 ? false : s.isLive }))
			},
			async handleGetContext (item) {
				const context = this.page?.context || {}
				const request = context.request
				const params = Object.assign({}, this.query, this.detail, item)
				const staticData = context.staticData ? await this.network.staticDataHandle(context.staticData, params) : {}
				const dynamicData = context.dynamicData || {}
				const newRequest = request ? await this.network.requestHandle(request, params) : null
				const response = newRequest ? await this.network.$request(newRequest) : {}
				const data = response ? await this.network.$list(dynamicData, response.data, response.taskId) : {}
				return Object.assign({}, item, staticData, data)
			},
			async handleGetBarrages (item) {
				const barrage = this.page?.barrages || {}
				const params = Object.assign({}, this.query, this.detail, item)
				const staticData = barrage.staticData ? await this.network.staticDataHandle(barrage.staticData, params) : []
				const dynamicData = barrage.dynamicData
				const request = barrage.request
				let data = []
				if ( dynamicData && request ) {
					const newRequest = await this.network.requestHandle(request, params)
					const response = await this.network.$request(newRequest)
					data = await this.network.$list(dynamicData, response.data, response.taskId)
				}
				return staticData.concat(data)
			},
			showModal () {
				this.modalShow = true
				this.$emit('scroll', 200)
				this.$nextTick(function () {
					this.handleModalPulldown()
				})
			},
			handleModalHide () {
				this.modalShow = false
				this.$emit('scroll', 0)
			},
			handleModalPulldown (callback) {
				this.$refs.list && this.$refs.list.initModule(callback, callback ? true : false)
			},
			showToast (data) {
				this.$refs.webview && this.$refs.webview.evalJS(`showToast('${encodeURIComponent(JSON.stringify(data))}');`)
			}
		}
	}
</script>

<style>
	.find_novel_tag {
		border-width: 1px;
		border-style: solid;
		border-radius: 5rpx;
		padding: 4rpx 10rpx;
	}
</style>